﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Globalization;

namespace DataAccessor
{
    /// <summary>
    /// 数据访问器工厂
    /// </summary>
    public static class Factory
    {
        /// <summary>
        /// 数据访问器的缓存
        /// </summary>
        private static Dictionary<string, IDataAccessor> _cache = new Dictionary<string, IDataAccessor>();

        /// <summary>
        /// 创建数据访问器
        /// </summary>
        /// <param name="databaseName">模块名</param>
        /// <returns>模块指定的数据访问器的一个实现的实例</returns>
        public static IDataAccessor Creater(string databaseName)
        {
            return Creater(databaseName, string.Empty);
        }

        /// <summary>
        /// 创建数据访问器
        /// </summary>
        /// <param name="databaseName">模块名</param>
        /// <param name="configName">配置名</param>
        /// <returns>模块指定的数据访问器的一个实现的实例</returns>
        public static IDataAccessor Creater(string databaseName, string configName)
        {
            string key = string.Format("{0}.{1}", databaseName, configName);
            if (!_cache.ContainsKey(key))
            {
                lock (_cache)
                {
                    if (!_cache.ContainsKey(key))
                    {
                        var holisticDatabase = HolisticCache.Holistic.Database.Single(database => database.Name.Equals(databaseName, StringComparison.CurrentCultureIgnoreCase));
                        var accessorType = Type.GetType(holisticDatabase.DataAccessor);
                        object accessor = null;
                        try
                        {
                            if (string.IsNullOrEmpty(configName))
                            {
                                accessor = Activator.CreateInstance(accessorType, databaseName);
                            }
                            else
                            {
                                accessor = Activator.CreateInstance(accessorType, databaseName, configName);
                            }
                        }
                        catch (TargetInvocationException ex)
                        {
                            throw ex.InnerException;
                        }
                        _cache.Add(key, accessor as IDataAccessor);
                    }
                }
            }

            return _cache[key];
        }
    }
}
